"""
@Time ： 2024/10/15 20:00
@Auth ： 莫天杨
@File ：parse.py
@IDE ：PyCharm
@Motto:大道无术
"""
from packet.kc_16 import *
from packet.kc_16.kc16_13 import whether_reset
from utils.common.crc16 import crc16_modbus_little_endian


def parse_authcode(raw_data):
    authcode_calc = crc16_modbus_little_endian(raw_data[:-4])
    authcode = f"{raw_data[-4:-2]} {raw_data[-2:]}"
    if authcode == authcode_calc:
        return f'{authcode}({authcode})'
    else:
        return f'BCC错误{authcode} 正确为:{authcode_calc}'


def whether_encryption(result):
    return "不加密" if result == '00' else "3DES" if result == '01' else "未知"


class KC16Parser:
    def __init__(self):
        self.message_types = {
            '01': parse_01_login_auth,  # 充电桩登录认证
            '02': parse_02_login_response,  # 登录认证应答
            '03': parse_03_heartbeat,  # 充电桩心跳包
            '04': parse_04_heartbeat_response,  # 心跳包应答
            '05': parse_05_Billing_Model_Verification_Request,  # 计费模型验证请求
            '06': parse_06_Billing_Model_Verification_Request_Response,  # 计费模型验证请求应答
            '09': parse_09_Billing_Model_Request,  # 充电桩计费模型请求
            '0A': parse_0A_Billing_Model_Request_Response,  # 充电桩计费模型请求应答
            '12': parse_12_Read_Realtime_Monitoring_Data,   # 读取实时监测数据
            '13': parse_13_Upload_Realtime_Monitoring_Data, # 上传实时监测数据
            '15': parse_15_Charging_Handshake,  # 充电握手
            '17': parse_17_Parameter_Config,    # 参数配置
            '19': parse_19_Charging_End,    # 充电结束
            '1B': parse_1B_Error_Message,   # 错误报文
            '1D': parse_1D_BMS_Suspend_During_Charging,  # 充电阶段BMS中止
            '21': parse_21_Charger_Suspend_During_Charging,  # 充电阶段充电机中止
            '23': parse_23_Charging_Process_BMS_Demand_and_Charger_Output,  # 充电过程 BMS 需求与充电机输出
            '25': parse_25_Charging_Process_BMS_messages,   # 充电过程 BMS 信息,
            '31': parse_31_Charging_Station_Applies_Start_Charging, # 充电桩主动申请启动充电
            '32': parse_32_Operational_Platform_Confirms_Charging_Initiation, # 运营平台确认启动充电
            '33': parse_33_Operational_Platform_Remote_Control_Start_Charging_Response, # 运营平台远程控制启机应答
            '34': parse_34_Operational_Platform_Remote_Control_Start_Charging,  # 运营平台远程控制启机
            '35': parse_35_Remote_Stop_Command_Response,    # 远程停机命令回复
            '36': parse_36_Operational_Platform_Remote_Stop,  # 运营平台远程停机
            '3B': parse_3B_Trade_Record,    # 交易记录
            '40': parse_40_Trade_Record_Confirm,    # 交易记录确认
            '41': parse_41_Balance_Update_Response,
            '42': parse_42_Remote_Account_Balance_Update,
            '43': parse_43_Offline_Card_Data_Response,  # 离线卡数据同步
            '44': parse_44_Offline_Card_Data_Sync,  # 离线卡数据统一应答
            # Add more message types and their corresponding parsing methods here
        }

    def get_message_name(self, message_id):
        message_id_mapping = {
            '01': '充电桩登录认证(充电桩->运营平台)',
            '02': '登录认证应答(运营平台->充电桩)',
            '03': '充电桩心跳包(充电桩->运营平台)',
            '04': '心跳包应答(运营平台->充电桩)',
            '05': '计费模型验证请求(充电桩->运营平台)',
            '06': '计费模型验证请求应答(运营平台->充电桩)',
            '09': '充电桩计费模型请求(充电桩->运营平台)',
            '0A': '充电桩计费模型请求应答(运营平台->充电桩)',
            '12': '读取实时监测数据(运营平台->充电桩)',
            '13': '上传实时监测数据(充电桩->运营平台)',
            '15': '充电握手(充电桩->运营平台)',
            '17': '参数配置(充电桩->运营平台)',
            '19': '充电结束(充电桩->运营平台)',
            '1B': '错误报文(充电桩->运营平台)',
            '1D': '充电阶段BMS中止(充电桩->运营平台)',
            '21': '充电阶段充电机中止(充电桩->运营平台)',
            '23': '充电过程 BMS 需求与充电机输出(充电桩->运营平台)',
            '25': '充电过程 BMS 信息(充电桩->运营平台)',
            '31': '充电桩主动申请启动充电(充电桩->运营平台)',
            '32': '运营平台确认启动充电(运营平台->充电桩)',
            '33': '运营平台远程控制启机应答(充电桩->运营平台)',
            '34': '运营平台远程控制启机(运营平台->充电桩)',
            '35': '远程停机命令回复(充电桩->运营平台)',
            '36': '运营平台远程停机(运营平台->充电桩)',
            '3B': '交易记录(充电桩->运营平台)',
            '40': '交易记录确认(运营平台->充电桩)',
            '41': '余额更新响应(充电桩->运营平台)',
            '42': '远程账户余额更新(运营平台->充电桩)',
            '43': '离线卡数据统一应答(充电桩->运营平台)',
            '44': '离线卡数据同步(运营平台->充电桩)',
            # Add more message types and their corresponding names here
        }
        return message_id_mapping.get(message_id, '未知消息')

    def parse_header(self, raw_data):
        header = raw_data[2:12]  # 假设消息头固定长度为 12 字节
        data = {
            "数据长度": f"{int(header[0:2], 16)}({header[0:2]})",
            "序列号域": f"{int(header[2:6], 16)}({header[2:6]})",
            "加密标志": f"{whether_encryption(header[6:8])}({header[6:8]})",
            "类      型": f"{KC16Parser.get_message_name(self, header[8:12])}({header[8:12]})",
        }
        # 前三行在同一行输出，第四行单独换行输出
        formatted_data = f"数据长度: {data['数据长度']}     序列号域: {data['序列号域']}    加密标志: {data['加密标志']} \n类      型:  {data['类      型']}\n"
        return formatted_data

    def parse_body(self, raw_data):
        # print(raw_data)
        header = raw_data[2:12]  #
        protocol_id = header[-2:]
        body = raw_data[12:]
        # 根据消息ID调用对应的解析方法
        if protocol_id in self.message_types:
            parse_method = self.message_types[protocol_id]
            return f'原始数据: {body}\n' + parse_method(body)
        else:
            return "不支持解析的协议包: {}".format(protocol_id)

    def parse(self, raw_data):
        # 解析消息头
        header_result = self.parse_header(raw_data)
        # 将解析结果合并并返回
        return (f'原始数据: {" ".join([raw_data[i:i+2] for i in range(0, len(raw_data), 2)])}\n'
                f'{header_result}'
                f'------------------------------------------------------消息体------------------------------------------'
                f'------------\n{self.parse_body(raw_data[:-4])}'
                f'校 验 码：{parse_authcode(raw_data[4:])}')





